/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.report.statistics.siteManagement;

import com.koron.common.bean.DepartmentTreeBean;
import com.koron.common.domain.KpiStatistics;
import com.koron.common.generator.DefaultIdGenerator;
import com.koron.common.generator.GetHardwareIdFailedException;
import com.koron.common.generator.InvalidSystemClockException;
import com.koron.common.service.KpiStatisticsService;
import com.koron.common.web.Util;
import com.koron.purpose.mapper.KPITemplateMapper;
import com.koron.report.bean.StatisticsBean;
import com.koron.report.management.StatisticsManagement;
import com.koron.report.mapper.statistics.InspecCompRateSpecialEquipMapper;
import com.koron.report.statistics.Contants;
import com.koron.report.statistics.StatisticsService;
import com.koron.risk.bean.CorpBean;
import com.koron.risk.service.api.CorpManagementService;
import com.koron.risk.util.BusinessCode;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 特种设备检验完成率
 */
@Service("inspecCompRateSpecialEquipService")
@SuppressWarnings("deprecation")
public class InspecCompRateSpecialEquipServiceImpl implements InitializingBean, StatisticsService {
    // 设备类型id,引用数据字典：特种设备 设备类型id
    private final String DEVICE_TYPE_ID = "1187936263681789952";

    // 指标code:特种设备实际检验总数
    private final String KPICODE_REALITY_TOTAL = "0065";
    // 指标code:特种设备检验计划检验总数
    private final String KPICODE_PLAN_TOTAL = "0066";
    // 指标code:特种设备检验完成率
    private final String KPICODE_PASS = "0067";

    private final Logger logger = LoggerFactory.getLogger(InspecCompRateSpecialEquipServiceImpl.class);

    @Autowired
    private StatisticsManagement statisticsManagement;

    @Autowired
    private KpiStatisticsService kpiStatisticsService;

    @Autowired
    private CorpManagementService corpManagementService;

    @Autowired
    private Util util;

    @Override
    public void afterPropertiesSet() throws Exception {
        Set<Object> handlers = statisticsManagement.getHandlers();
        handlers.add(this);
    }

    @Override
    public void statisticsMonth(int year, int month) {

    }

    @Override
    public void statisticsQuarter(int year, int quarter) {

    }

    @Override
    public void statisticsYear(int year) {
        SessionFactory factory = null;
        try {
            factory = new SessionFactory();
            InspecCompRateSpecialEquipMapper mapper = factory.getMapper(InspecCompRateSpecialEquipMapper.class);
            Calendar calendar = Calendar.getInstance();
            calendar.set(year, 0, 1, 0, 0, 0);
            Date startDate = calendar.getTime();
            calendar.add(Calendar.YEAR, 1);
            Date stopDate = calendar.getTime();

            // 特种设备检验 检验完成数 指标名称
            String kpiNameRealityTotal = factory.getMapper(KPITemplateMapper.class).queryTemplateByCode(KPICODE_REALITY_TOTAL).getName();
            // 特种设备检验 应检验总数 指标名称
            String kpiNamePlanTotal = factory.getMapper(KPITemplateMapper.class).queryTemplateByCode(KPICODE_PLAN_TOTAL).getName();
            // 特种设备检验完成率 指标名称
            String kpiNamePass = factory.getMapper(KPITemplateMapper.class).queryTemplateByCode(KPICODE_PASS).getName();

            String dateValue = String.valueOf(year);
            // 按部门
            deptTotal(mapper, kpiNameRealityTotal, kpiNamePlanTotal, kpiNamePass,
                    Contants.DATE_TYPE_3, dateValue, Contants.STATISTICAL_TYPE_2, startDate, stopDate);
            // 按公司
            companyTotal(mapper, kpiNameRealityTotal, kpiNamePlanTotal, kpiNamePass,
                    Contants.DATE_TYPE_3, dateValue, Contants.STATISTICAL_TYPE_3, startDate, stopDate);
        } catch (Exception e) {
            if (factory != null) {
                factory.close(false);
            }
            logger.error("特种设备检验完成率按年(" + year + ")统计执行发生错误");
        }finally {
            if (factory != null) {
                factory.close();
            }
        }
    }

    /**
     * 按部门 统计
     *
     * @param mapper
     * @param kpiNameRealityTotal 特种设备检验 检验完成数 指标名称
     * @param kpiNamePlanTotal    特种设备检验 应检验总数 指标名称
     * @param kpiNamePass         特种设备检验完成率 指标名称
     * @param dateType            日期类型 1月，2季，3年
     * @param dateValue           日期 月：2020-01，季2020-1/2/3/4,年2020
     * @param statisticalType     统计类型：1员工，2部门，3公司，4片区，5集团
     * @param startDate
     * @param stopDate
     * @throws GetHardwareIdFailedException
     * @throws InvalidSystemClockException
     */
    private void deptTotal(InspecCompRateSpecialEquipMapper mapper, String kpiNameRealityTotal, String kpiNamePlanTotal,
                           String kpiNamePass, Integer dateType, String dateValue, Integer statisticalType,
                           Date startDate, Date stopDate) throws GetHardwareIdFailedException, InvalidSystemClockException {
        // 统计查询:特种设备检验 检验完成数 指标名称
        List<StatisticsBean> realityTotalList = mapper.statisticsDept(startDate, stopDate, DEVICE_TYPE_ID);
        // 统计查询:特种设备检验 应检验总数 指标名称
        List<StatisticsBean> planTotalList = mapper.statisticsTotalDept(startDate, stopDate, DEVICE_TYPE_ID);
        if (planTotalList == null || planTotalList.size() <= 0) {
            return;
        }
        //先获取当前组织架构上所有的部门
        List<DepartmentTreeBean> departmentTreeBeanList = (List<DepartmentTreeBean>) util.depttree(Contants.BLOC_CODE, 1).getData();
        if (departmentTreeBeanList == null || departmentTreeBeanList.size() <= 0) {
            return;
        }
        // 将当前获取的所有部门排除当前为水司，以及当前集团的的code
        //先排除集团
        departmentTreeBeanList = departmentTreeBeanList.stream()
                .filter(dept -> !Contants.BLOC_CODE.equals(dept.getDepartmentCode()))
                .collect(Collectors.toList());
        //获取当前标志为水司的部门（组织架构）
        List<CorpBean> corpBeanList = corpManagementService.corpBeanList();
        List<String> corpCodeList = corpBeanList.stream()
                .map(corpBean -> corpBean.getCorpCode())
                .collect(Collectors.toList());
        //再排除水司
        departmentTreeBeanList = departmentTreeBeanList.stream()
                .filter(dept -> !(corpCodeList.contains(dept.getDepartmentCode())))
                .collect(Collectors.toList());
        if (departmentTreeBeanList == null || departmentTreeBeanList.size() <= 0) {
            return;
        }
        // 特种设备检验 检验完成数
        List<StatisticsBean> realityTotals = new LinkedList<>();
        // 特种设备检验 应检验总数
        List<StatisticsBean> planTotals = new LinkedList<>();
        MessageBean<?> msg;
        List<String> codes;
        List<DepartmentTreeBean> list;
        float value;
        for (DepartmentTreeBean departmentTreeBean : departmentTreeBeanList) {
            //查询该部门下所有子部门
            msg = util.depttree(departmentTreeBean.getDepartmentCode(), 1);
            codes = new LinkedList<>();
            if (msg.getData() != null) {
                list = (List<DepartmentTreeBean>) msg.getData();
                codes = list.stream().map(bean -> bean.getDepartmentCode()).collect(Collectors.toList());
            } else {
                codes.add(departmentTreeBean.getDepartmentCode());
            }
            value = 0f;
            for (StatisticsBean bean : planTotalList) {
                if (codes.contains(bean.getCode())) {
                    value += Float.valueOf(bean.getValue());
                }
            }
            if (value != 0f) {
                planTotals.add(new StatisticsBean(departmentTreeBean.getDepartmentCode(), departmentTreeBean.getName(), String.valueOf(value)));
            }
            if (realityTotalList != null && realityTotalList.size() > 0) {
                value = 0f;
                for (StatisticsBean bean : realityTotalList) {
                    if (codes.contains(bean.getCode())) {
                        value += Float.valueOf(bean.getValue());
                    }
                }
                if (value != 0f) {
                    realityTotals.add(new StatisticsBean(departmentTreeBean.getDepartmentCode(), departmentTreeBean.getName(), String.valueOf(value)));
                }
            }
        }
        // 组装数据：进行统计指标添加
        assemblyData(planTotals, realityTotals, kpiNameRealityTotal, kpiNamePlanTotal,
                kpiNamePass, dateType, dateValue, statisticalType);
    }

    /**
     * 按部门 统计
     *
     * @param mapper
     * @param kpiNameRealityTotal 特种设备检验 检验完成数 指标名称
     * @param kpiNamePlanTotal    特种设备检验 应检验总数 指标名称
     * @param kpiNamePass         特种设备检验完成率 指标名称
     * @param dateType            日期类型 1月，2季，3年
     * @param dateValue           日期 月：2020-01，季2020-1/2/3/4,年2020
     * @param statisticalType     统计类型：1员工，2部门，3公司，4片区，5集团
     * @param startDate
     * @param stopDate
     * @throws GetHardwareIdFailedException
     * @throws InvalidSystemClockException
     */
    private void companyTotal(InspecCompRateSpecialEquipMapper mapper, String kpiNameRealityTotal, String kpiNamePlanTotal,
                              String kpiNamePass, Integer dateType, String dateValue, Integer statisticalType,
                              Date startDate, Date stopDate) throws GetHardwareIdFailedException, InvalidSystemClockException {
        // 统计查询:特种设备检验 检验完成数list
        List<StatisticsBean> realityTotalList = mapper.statisticsCompany(startDate, stopDate, DEVICE_TYPE_ID);
        // 统计查询:特种设备检验 应检验总数list
        List<StatisticsBean> planTotalList = mapper.statisticsTotalCompany(startDate, stopDate, DEVICE_TYPE_ID);
        if (planTotalList != null && planTotalList.size() > 0) {
            MessageBean<CorpBean> corpBean;
            for (StatisticsBean statisticsBean : planTotalList) {
                // 获取水司名称
                corpBean = corpManagementService.getOne(statisticsBean.getCode());
                if (corpBean.getCode() == BusinessCode.MESSAGE_CODE_SUCCESS) {
                    statisticsBean.setCodeName(corpBean.getData().getCorpName());
                } else {
                    statisticsBean.setCodeName("");
                }
            }
        }
        // 组装数据：进行统计指标添加
        assemblyData(planTotalList, realityTotalList, kpiNameRealityTotal, kpiNamePlanTotal,
                kpiNamePass, dateType, dateValue, statisticalType);
    }

    /**
     * 组装数据：进行统计指标添加
     *
     * @param planTotalList       特种设备检验 应检验总数list
     * @param realityTotalList    特种设备检验 检验完成数list
     * @param kpiNameRealityTotal 特种设备检验 检验完成数 指标名称
     * @param kpiNamePlanTotal    特种设备检验 应检验总数 指标名称
     * @param kpiNamePass         特种设备检验完成率 指标名称
     * @param dateType            日期类型 1月，2季，3年
     * @param dateValue           日期 月：2020-01，季2020-1/2/3/4,年2020
     * @param statisticalType     统计类型：1员工，2部门，3公司，4片区，5集团
     * @throws GetHardwareIdFailedException
     * @throws InvalidSystemClockException
     */
    private void assemblyData(List<StatisticsBean> planTotalList, List<StatisticsBean> realityTotalList,
                              String kpiNameRealityTotal, String kpiNamePlanTotal, String kpiNamePass,
                              Integer dateType, String dateValue, Integer statisticalType) throws GetHardwareIdFailedException, InvalidSystemClockException {
        // 统计查询:特种设备检验完成率
        if (planTotalList != null && planTotalList.size() > 0) {
            List<KpiStatistics> insertList = new LinkedList<>();
            for (StatisticsBean statisticsBean : planTotalList) {
                float value = 0f;
                // 特种设备检验 检验完成数
                if (realityTotalList != null && realityTotalList.size() > 0) {
                    for (StatisticsBean realityTotal : realityTotalList) {
                        if (statisticsBean.getCode().equals(realityTotal.getCode())) {
                            value = Float.valueOf(realityTotal.getValue());
                            break;
                        }
                    }
                }
                insertList.add(new KpiStatistics(
                        DefaultIdGenerator.getInstance().generateLongId(),
                        kpiNameRealityTotal,
                        KPICODE_REALITY_TOTAL,
                        value,
                        dateType,
                        dateValue,
                        statisticalType,
                        statisticsBean.getCode(),
                        statisticsBean.getCodeName(),
                        new Date()
                ));
                // 特种设备检验 应检验总数
                insertList.add(new KpiStatistics(
                        DefaultIdGenerator.getInstance().generateLongId(),
                        kpiNamePlanTotal,
                        KPICODE_PLAN_TOTAL,
                        Float.valueOf(statisticsBean.getValue()),
                        dateType,
                        dateValue,
                        statisticalType,
                        statisticsBean.getCode(),
                        statisticsBean.getCodeName(),
                        new Date()
                ));
                // 特种设备检验完成率
                float percentPass = Float.valueOf(statisticsBean.getValue());
                if (percentPass != 0f) {
                    percentPass = value / percentPass;
                }
                insertList.add(new KpiStatistics(
                        DefaultIdGenerator.getInstance().generateLongId(),
                        kpiNamePass,
                        KPICODE_PASS,
                        percentPass,
                        dateType,
                        dateValue,
                        statisticalType,
                        statisticsBean.getCode(),
                        statisticsBean.getCodeName(),
                        new Date()
                ));
                kpiStatisticsService.delete(KPICODE_REALITY_TOTAL, dateValue, statisticsBean.getCode());
                kpiStatisticsService.delete(KPICODE_PLAN_TOTAL, dateValue, statisticsBean.getCode());
                kpiStatisticsService.delete(KPICODE_PASS, dateValue, statisticsBean.getCode());
            }
            kpiStatisticsService.batchInsert(insertList);
        }
    }
}
